import sys
import struct
import pathlib
import pickle
import socket
import json
from PyQt5.QtWidgets import (QApplication, QMessageBox, QWidget)
from PyQt5 import uic
from PyQt5 import QtWidgets
from ui import ui_login
import chat

class RegisterWinodw:
    def __init__(self, loginUi, rootSocket):
        self.ui = uic.loadUi(pathlib.Path(__file__).resolve().parent.joinpath('ui').joinpath('register.ui'))
        self.ui.BLoginin.clicked.connect(self.showLoginUi)
        self.ui.BRegister.clicked.connect(self.registerClick)
        self.loginUi = loginUi
        self.rootSocket = rootSocket

    def showLoginUi(self):
        self.loginUi.show()
        self.ui.close()

    def registerClick(self):
            username = self.ui.EUsername.text().strip()
            password = self.ui.EPassword.text().strip()
            password2 = self.ui.EPassword2.text().strip()
            if not username:
                QMessageBox.warning(self.ui, '输入错误', '账号不能为空')
                return
            elif not password or not password2:
                QMessageBox.warning(self.ui, '输入错误', '密码不能为空')
                return
            elif password != password2:
                QMessageBox.warning(self.ui, '输入错误', '两次密码不一致')
                return

            # make usesrname and password
            registerData = json.dumps({"username": username, "password": password})
            dataHeader = json.dumps({"dataSize": len(registerData), "dataClass": "register"})
            # send header size
            self.rootSocket.send(struct.pack('i', len(dataHeader)))
            self.rootSocket.send(dataHeader.encode())
            # send data
            self.rootSocket.send(registerData.encode())
            # 接收是否注册成功
            islogin = json.loads((self.rootSocket.recv(20)).decode())
            if not islogin['code']:
                QMessageBox.warning(self.ui, '服务器错误', '用户名已经存在')
                return
            QMessageBox.about(self.ui, '注册成功', '快去登录吧')

class Window(QWidget):
    def __init__(self):
        super().__init__()
        # loginUi init
        self.loginUi = ui_login.Ui_Form()
        self.loginUi.setupUi(self)
        # button connect
        self.loginUi.BLoginin.clicked.connect(self.loginClick)

        self.loginUi.BRegister.clicked.connect(self.registerClick)
        # checkbox connect
        self.loginUi.RCbox1.clicked.connect(self.cb1Click)
        self.loginUi.RCbox2.clicked.connect(self.cb2Click)
        ## checkbox settings
        self.dataPath = pathlib.Path(__file__).resolve().parent.joinpath('data')
        self.ckBoxSetting()

    def initRegisterUi(self):
        # registerUi init
        self.registerUi = RegisterWinodw(self, self.rootSocket)
        
    def initChatUi(self):
        self.chatUi = chat.Window()

    def initServer(self):
        self.rootSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        rootAddr = ('127.0.0.1', 3000)
        try:
            self.rootSocket.connect(rootAddr)
            return True
        except:
            QMessageBox.warning(self, '无法连接服务器', '请重启程序')
            return False

    def ckBoxSetting(self):
        if not self.dataPath.joinpath('user.pkl').exists():
            self.isCbox1 = 0
            self.isCbox2 = 0
            self.loginUi.RCbox1.setChecked(True if self.isCbox1 else False)
            self.loginUi.RCbox2.setChecked(True if self.isCbox2 else False)
            return

        with open(self.dataPath.joinpath('user.pkl'), 'rb') as f:
            userData = pickle.load(f)
            print(userData)
            self.isCbox1 = userData['isCbox1']
            self.isCbox2 = userData['isCbox2']
            if self.isCbox1:
                self.loginUi.RCbox1.setChecked(True if self.isCbox1 else False)
                self.loginUi.EUsername.setText(userData['username'])
            if self.isCbox2:
                self.loginUi.RCbox2.setChecked(True if self.isCbox2 else False)
                self.loginUi.EPassword.setText(userData['password'])

    def cb1Click(self):
        self.isCbox1 = self.loginUi.RCbox1.checkState()
        print(self.isCbox1)

    def cb2Click(self):
        self.isCbox2 = self.loginUi.RCbox2.checkState()
        print(self.isCbox2)

    def closeEvent(self, event):
        # 重新closeevent函数
        with open(self.dataPath.joinpath('user.pkl'), 'wb') as f:
            userData = {'isCbox1': self.isCbox1, 'isCbox2': self.isCbox2}
            if self.isCbox1: userData['username'] = self.loginUi.EUsername.text().strip()
            if self.isCbox2: userData['password'] = self.loginUi.EPassword.text().strip()
            pickle.dump(userData, f)

    def loginClick(self):
        username = self.loginUi.EUsername.text().strip()
        password = self.loginUi.EPassword.text().strip()
        if not username: 
            QMessageBox.warning(self, '输入错误', '账号不能为空')
            return
        elif not password: 
            QMessageBox.warning(self, '输入错误', '密码不能为空')
            return
        # send username and password
        loginData = json.dumps({"username": username, "password": password})
        dataHeader = json.dumps({"dataSize": len(loginData), "dataClass": "loginIn"})
        # send header size
        self.rootSocket.send(struct.pack('i', len(dataHeader)))
        self.rootSocket.send(dataHeader.encode())
        # send data
        self.rootSocket.send(loginData.encode())

        # 接收从服务器返回的匹配结果
        islogin = json.loads((self.rootSocket.recv(20)).decode())
        if not islogin['code']:
            QMessageBox.warning(self, '服务器错误', '请检查账号或密码是否正确')
            return
        self.chatUi.show()
        self.close()

    def registerClick(self):
        self.registerUi.ui.show()
        self.close()

if __name__ == '__main__':
    app=QApplication(sys.argv)

    window=Window()
    window.show()
    ## server init
    if not window.initServer():
        sys.exit()
    ## registerUi init
    window.initRegisterUi()
    ## chatUi init
    window.initChatUi()

    sys.exit(app.exec_())
